www.gusucode.com > VC++仿XP免费Prof UIS界面库-源码程序 > VC++仿XP免费Prof UIS界面库-源码程序/code/Src/ExtButton.cpp
//Download by http://www.NewXing.com // This is part of the Professional User Interface Suite library. // Copyright (C) 2001-2004 FOSS Software, Inc. // All rights reserved. // // http://www.prof-uis.com // http://www.fossware.com // mailto:foss@fossware.com // // This source code can be used, modified and redistributed // under the terms of the license agreement that is included // in the Professional User Interface Suite package. // // Warranties and Disclaimers: // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND // INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. // IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT, // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES, // INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA, // INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. #include "stdafx.h" #include "ExtButton.h" #include "ExtCmdManager.h" #include "ExtPaintManager.h" #include "ExtMemoryDC.h" #include "ExtPopupMenuWnd.h" #include "ExtColorDlg.h" #include "ExtToolControlBar.h" #if (!defined __AFXPRIV_H__) #include <AfxPriv.h> #endif #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif CExtButton::CExtButton() { m_hIconIn = NULL; m_hIconOut = NULL; m_hCursor = NULL; m_bIsFlat = FALSE; m_bDrawBorder = TRUE; m_bSeparatedDropDown = FALSE; m_bAutoChangeID = m_bAutoChangeCmdIcon = FALSE; m_bMouseOver = m_bPushed = m_bPushTracking = m_bKeyTracking = FALSE; m_nTrackingHT = 0; m_nAlign = CExtPaintManager::e_align_t::__ALIGN_HORIZ_CENTER |CExtPaintManager::e_align_t::__ALIGN_VERT ; m_bIsDefault = FALSE; m_wndToolTip.m_hWnd = NULL; m_dwMenuOpt = TPMX_TOPALIGN; m_nMenuLeftAreaWidth = 0; } CExtButton::~CExtButton() { _FreeWinObjects(); } void CExtButton::_FreeWinObjects() { if( m_hIconIn != NULL ) ::DestroyIcon( m_hIconIn ); if( m_hIconOut != NULL ) ::DestroyIcon( m_hIconOut ); if( m_hCursor != NULL ) ::DestroyCursor(m_hCursor); } IMPLEMENT_DYNCREATE(CExtButton, CButton); BEGIN_MESSAGE_MAP(CExtButton, CButton) //{{AFX_MSG_MAP(CExtButton) ON_WM_CAPTURECHANGED() ON_WM_SETCURSOR() ON_WM_KILLFOCUS() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_PAINT() ON_WM_ERASEBKGND() ON_WM_ENABLE() //}}AFX_MSG_MAP ON_REGISTERED_MESSAGE( CExtToolControlBar::g_nMsgPutToPopupMenu, _OnPutToPopupMenuImpl ) ON_WM_SYSCOLORCHANGE() __EXT_MFC_SAFE_ON_WM_SETTINGCHANGE() ON_MESSAGE(WM_DISPLAYCHANGE, OnDisplayChange) ON_MESSAGE(__ExtMfc_WM_THEMECHANGED, OnThemeChanged) END_MESSAGE_MAP() LRESULT CExtButton::_OnPutToPopupMenuImpl(WPARAM wParam, LPARAM lParam) { lParam; CExtPopupMenuWnd * pPopup = reinterpret_cast < CExtPopupMenuWnd * > (wParam); ASSERT_VALID( pPopup ); return OnPutToPopupMenu( pPopup ) ? TRUE : FALSE; } bool CExtButton::OnPutToPopupMenu( CExtPopupMenuWnd * pPopup ) { ASSERT_VALID( pPopup ); //bool bInBar = false; //CWnd * pWnd = GetParent(); // ASSERT_VALID( pWnd ); // if( pWnd->IsKindOf(RUNTIME_CLASS(CControlBar)) ) // { // bInBar = true; // pWnd = pWnd->GetParentFrame(); // ASSERT_VALID( pWnd ); // if( pWnd->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) ) // { // pWnd = pWnd->GetParentFrame(); // ASSERT_VALID( pWnd ); // } // } if( m_menu.GetSafeHmenu() != NULL ) { ASSERT( ::IsMenu( m_menu.GetSafeHmenu() ) ); CExtPopupMenuWnd * pPopupIns = new CExtPopupMenuWnd; VERIFY( pPopupIns->CreatePopupMenu( //pWnd->GetSafeHwnd() pPopup->GetCmdRecieverHWND() ) ); VERIFY( pPopupIns->UpdateFromMenu( pPopup->GetCmdRecieverHWND(), &m_menu ) ); HICON hIcon = NULL; if( m_hIconIn != NULL ) { CExtCmdIcon _icon( m_hIconIn, true ); hIcon = _icon.DetachAsHICON(); } CString sPopupText( _T("") ); CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() ), GetDlgCtrlID() ); if( pCmdItem != NULL ) sPopupText = pCmdItem->m_sMenuText; if( sPopupText.IsEmpty() ) GetWindowText( sPopupText ); VERIFY( pPopup->ItemInsertSpecPopup( pPopupIns, -1, (LPCTSTR)sPopupText, hIcon ) ); return true; } return false; } void CExtButton::SetIcon(int nIconInId, int nIconOutId) { HICON hIconIn; HICON hIconOut; HINSTANCE hInstResource = AfxFindResourceHandle( MAKEINTRESOURCE(nIconInId), RT_GROUP_ICON ); hIconIn = (HICON)::LoadImage( hInstResource, MAKEINTRESOURCE(nIconInId), IMAGE_ICON, 0, 0, 0 ); hIconOut = (nIconOutId == NULL) ? NULL : (HICON)::LoadImage( hInstResource, MAKEINTRESOURCE(nIconOutId), IMAGE_ICON, 0, 0, 0 ); SetIcon(hIconIn, hIconOut); } void CExtButton::SetIcon(HICON hIconIn, HICON hIconOut) { if( m_hIconIn != NULL) ::DestroyIcon( m_hIconIn ); if( m_hIconOut != NULL) ::DestroyIcon( m_hIconOut ); m_hIconIn = hIconIn; m_hIconOut = (hIconOut == NULL) ? m_hIconIn : hIconOut; if( GetSafeHwnd() != NULL && ::IsWindow( GetSafeHwnd() ) ) { Invalidate(); UpdateWindow(); } } BOOL CExtButton::SetBtnCursor(int nCursorId) { HINSTANCE hInstResource; if( m_hCursor != NULL ) ::DestroyCursor(m_hCursor); m_hCursor = NULL; if( nCursorId != -1 ) { hInstResource = AfxFindResourceHandle( MAKEINTRESOURCE(nCursorId), RT_GROUP_CURSOR ); m_hCursor = (HCURSOR)::LoadImage( hInstResource, MAKEINTRESOURCE(nCursorId), IMAGE_CURSOR, 0, 0, 0 ); if( m_hCursor == NULL ) { m_hCursor = ::LoadCursor( NULL, MAKEINTRESOURCE(nCursorId) ); if( m_hCursor == NULL ) return FALSE; } } return TRUE; } void CExtButton::SetFlat( BOOL bState ) { m_bIsFlat = bState; if( GetSafeHwnd() != NULL && ::IsWindow( GetSafeHwnd() ) ) { Invalidate(); UpdateWindow(); } } BOOL CExtButton::GetFlat() const { return m_bIsFlat; } void CExtButton::SetAlign( int nAlign ) { switch( nAlign ) { case CExtPaintManager::e_align_t::__ALIGN_HORIZ_CENTER: m_nAlign = CExtPaintManager::e_align_t::__ALIGN_HORIZ_CENTER; break; case CExtPaintManager::e_align_t::__ALIGN_HORIZ_RIGHT: m_nAlign = CExtPaintManager::e_align_t::__ALIGN_HORIZ_RIGHT; break; case CExtPaintManager::e_align_t::__ALIGN_VERT: m_nAlign = CExtPaintManager::e_align_t::__ALIGN_VERT; break; } // switch( nAlign ) if( GetSafeHwnd() != NULL && ::IsWindow( GetSafeHwnd() ) ) { Invalidate(); UpdateWindow(); } } int CExtButton::GetAlign() const { return m_nAlign; } BOOL CExtButton::GetDrawBorder() const { return m_bDrawBorder; } void CExtButton::SetDrawBorder( BOOL bEnable ) { m_bDrawBorder = bEnable; if( GetSafeHwnd() != NULL && ::IsWindow( GetSafeHwnd() ) ) { Invalidate(); UpdateWindow(); } } BOOL CExtButton::GetSeparatedDropDown() const { return m_bSeparatedDropDown; } void CExtButton::SetSeparatedDropDown( BOOL bSeparatedDropDown // = TRUE ) { m_bSeparatedDropDown = bSeparatedDropDown; if( GetSafeHwnd() != NULL && ::IsWindow( GetSafeHwnd() ) ) { Invalidate(); UpdateWindow(); } } BOOL CExtButton::GetAutoChangeID() const { return m_bAutoChangeID; } void CExtButton::SetAutoChangeID( BOOL bAutoChangeID // = TRUE ) { m_bAutoChangeID = bAutoChangeID; } BOOL CExtButton::GetAutoChangeCmdIcon() const { return m_bAutoChangeCmdIcon; } void CExtButton::SetAutoChangeCmdIcon( BOOL bAutoChangeCmdIcon // = TRUE ) { m_bAutoChangeCmdIcon = bAutoChangeCmdIcon; } void CExtButton::_CalcClientRects( CRect & rcMainArea, CRect & rcDropDown ) const { GetClientRect( &rcMainArea ); rcDropDown = rcMainArea; rcDropDown.left = rcDropDown.right; if( !m_bSeparatedDropDown ) return; rcDropDown.left -= __DROPDOWN_ARROW_GAP*2 + CExtPaintManager::g_glyph_btn_expand_bottom.Size().cx ; rcMainArea.right = rcDropDown.left; } INT CExtButton::_HtMouseOnButton( const POINT & ptClient ) const // 0 - not, 1-main area, 2-dropdown area { CRect rcMainArea, rcDropDown; _CalcClientRects( rcMainArea, rcDropDown ); if( rcMainArea.PtInRect(ptClient) ) return 1; if( !m_bSeparatedDropDown ) return 0; if( rcDropDown.PtInRect(ptClient) ) return 2; return 0; } INT CExtButton::_HtMouseOnButton() const // 0 - not, 1-main area, 2-dropdown area { POINT point; if( ! ::GetCursorPos( &point ) ) return 0; HWND hWndUnderMouse = ::WindowFromPoint( point ); if( hWndUnderMouse == NULL || hWndUnderMouse != m_hWnd ) return false; if( !m_bSeparatedDropDown ) return 1; ScreenToClient( &point ); return _HtMouseOnButton( point ); } void CExtButton::OnMouseMove(UINT nFlags, CPoint point) { if( m_bKeyTracking ) return; CButton::OnMouseMove(nFlags, point); INT nTrackingHT = _HtMouseOnButton(); if( ( ((!m_bPushTracking) && nTrackingHT!=0) || ( m_bPushTracking && nTrackingHT==m_nTrackingHT ) ) && CExtPopupMenuWnd::TestHoverEnabledFromActiveHWND( GetSafeHwnd() ) ) { // if mouse is really on button if( CExtMouseCaptureSink::GetCapture() != GetSafeHwnd() ) CExtMouseCaptureSink::SetCapture( GetSafeHwnd() ); if( m_bMouseOver ) return; m_bMouseOver = TRUE; m_bPushed = ((nFlags & MK_LBUTTON) && m_bPushTracking ) ? TRUE : FALSE; Invalidate(); UpdateWindow(); } // if mouse is really on button else { // if mouse is really NOT on button if( CExtMouseCaptureSink::GetCapture() == GetSafeHwnd() && ( !m_bPushTracking ) ) CExtMouseCaptureSink::ReleaseCapture(); if( !m_bMouseOver ) return; m_bMouseOver = m_bPushed = FALSE; Invalidate(); UpdateWindow(); } // if mouse is really NOT on button } void CExtButton::OnKillFocus(CWnd * pNewWnd) { CButton::OnKillFocus(pNewWnd); if( m_bMouseOver || m_bPushed ) { if( CExtMouseCaptureSink::GetCapture() == GetSafeHwnd() ) CExtMouseCaptureSink::ReleaseCapture(); m_bMouseOver = m_bPushed = FALSE; Invalidate(); UpdateWindow(); } } void CExtButton::OnCaptureChanged(CWnd *pWnd) { if( (m_bMouseOver || m_bPushed) && pWnd != this ) { // CExtMouseCaptureSink::ReleaseCapture(); m_bMouseOver = m_bPushed = FALSE; Invalidate(); UpdateWindow(); } CButton::OnCaptureChanged(pWnd); } void CExtButton::PreSubclassWindow() { CButton::PreSubclassWindow(); UINT nBS = GetButtonStyle(); if( nBS & BS_DEFPUSHBUTTON ) m_bIsDefault = TRUE; if( nBS & BS_OWNERDRAW ) SetButtonStyle( nBS & ~(BS_OWNERDRAW) ); SetFont( m_bIsDefault ? &g_PaintManager->m_FontBold : &g_PaintManager->m_FontNormal , FALSE ); PostMessage( // delayed repainting WM_ENABLE, (WPARAM)IsWindowEnabled() ); } BOOL CExtButton::PreTranslateMessage(MSG* pMsg) { if( !CExtPopupMenuWnd::IsMenuTracking() ) { InitToolTip(); m_wndToolTip.RelayEvent(pMsg); } // if( CExtPopupMenuWnd::IsMenuTracking() ) // return TRUE; if( ( pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP ) && ( pMsg->wParam == VK_RETURN || pMsg->wParam == VK_SPACE ) ) { if( IsWindowEnabled() && IsWindowVisible() && (!m_bPushTracking) ) { if( (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) || (pMsg->message == WM_KEYUP && pMsg->wParam == VK_SPACE) ) { if( CExtMouseCaptureSink::GetCapture() == GetSafeHwnd() ) CExtMouseCaptureSink::ReleaseCapture(); m_bMouseOver = m_bPushed = m_bPushTracking = m_bKeyTracking = FALSE; Invalidate(); UpdateWindow(); _OnClick( true, false ); return TRUE; } if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE) { m_bMouseOver = m_bPushed = m_bKeyTracking = TRUE; CExtMouseCaptureSink::SetCapture( GetSafeHwnd() ); Invalidate(); UpdateWindow(); return TRUE; } } // if( IsWindowEnabled() && IsWindowVisible() && (!m_bPushTracking) ) return TRUE; } return CButton::PreTranslateMessage(pMsg); } LRESULT CExtButton::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) { bool bInvalidate = false; switch( message ) { case WM_LBUTTONDBLCLK: message = WM_LBUTTONDOWN; break; case BM_SETCHECK: case BM_SETSTATE: case BM_SETSTYLE: #if (WINVER >= 0x0400) case BM_CLICK: case BM_SETIMAGE: #endif case WM_SETTEXT: case WM_SIZE: case WM_WINDOWPOSCHANGED: bInvalidate = true; break; } // switch( message ) LRESULT lResult = CButton::DefWindowProc(message, wParam, lParam); if( bInvalidate ) { Invalidate(); UpdateWindow(); } return lResult; } BOOL CExtButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if( m_hCursor != NULL ) { ::SetCursor(m_hCursor); return TRUE; } return CButton::OnSetCursor(pWnd, nHitTest, message); } void CExtButton::SetTooltipText(CExtSafeString* spText, BOOL bActivate) { if( spText == NULL ) return; InitToolTip(); if( m_wndToolTip.GetToolCount() == 0 ) { CRect rectBtn; GetClientRect(rectBtn); m_wndToolTip.AddTool( this, *spText, rectBtn, 1 ); } m_wndToolTip.UpdateTipText( *spText, this, 1 ); m_wndToolTip.Activate(bActivate); } void CExtButton::SetTooltipText(CExtSafeString & sText, BOOL bActivate) { if( sText.IsEmpty() ) return; InitToolTip(); if( m_wndToolTip.GetToolCount() == 0 ) { CRect rectBtn; GetClientRect(rectBtn); m_wndToolTip.AddTool( this, sText, rectBtn, 1 ); } m_wndToolTip.UpdateTipText( sText, this, 1 ); m_wndToolTip.Activate( bActivate ); } void CExtButton::SetTooltipText(__EXT_MFC_SAFE_LPCTSTR sText, BOOL bActivate) { if( sText == NULL || _tcslen( sText ) == 0 ) return; InitToolTip(); if( m_wndToolTip.GetToolCount() == 0 ) { CRect rectBtn; GetClientRect(rectBtn); m_wndToolTip.AddTool(this,sText,rectBtn,1); } m_wndToolTip.UpdateTipText(sText,this,1); m_wndToolTip.Activate(bActivate); } void CExtButton::SetTooltipText(int nId, BOOL bActivate) { CExtSafeString sText; sText.LoadString(nId); if( !sText.IsEmpty() ) SetTooltipText(&sText, bActivate); } void CExtButton::ActivateTooltip(BOOL bActivate) { if( m_wndToolTip.GetToolCount() == 0 ) return; m_wndToolTip.Activate(bActivate); } BOOL CExtButton::GetDefault() const { return m_bIsDefault; } void CExtButton::InitToolTip() { if( m_wndToolTip.m_hWnd == NULL ) { m_wndToolTip.Create(this); m_wndToolTip.Activate(FALSE); } } void CExtButton::OnSysColorChange() { CButton::OnSysColorChange(); g_PaintManager.OnSysColorChange( this ); g_CmdManager.OnSysColorChange( this ); } void CExtButton::OnSettingChange(UINT uFlags, __EXT_MFC_SAFE_LPCTSTR lpszSection) { CButton::OnSettingChange( uFlags, lpszSection ); g_PaintManager.OnSettingChange( this, uFlags, lpszSection ); g_CmdManager.OnSettingChange( this, uFlags, lpszSection ); } LRESULT CExtButton::OnDisplayChange( WPARAM wParam, LPARAM lParam ) { LRESULT lResult = CButton::OnDisplayChange( wParam, lParam ); g_PaintManager.OnDisplayChange( this, (INT)wParam, CPoint(lParam) ); g_CmdManager.OnDisplayChange( this, (INT)wParam, CPoint(lParam) ); return lResult; } LRESULT CExtButton::OnThemeChanged( WPARAM wParam, LPARAM lParam ) { LRESULT lResult = Default(); g_PaintManager.OnThemeChanged( this, wParam, lParam ); g_CmdManager.OnThemeChanged( this, wParam, lParam ); return lResult; } void CExtButton::OnLButtonDown(UINT nFlags, CPoint point) { if( m_bKeyTracking ) return; CButton::OnLButtonDown( nFlags, point ); m_nTrackingHT = _HtMouseOnButton(); if( m_nTrackingHT == 0 ) return; m_bMouseOver = m_bPushed = m_bPushTracking = TRUE; CExtMouseCaptureSink::SetCapture( GetSafeHwnd() ); Invalidate(); UpdateWindow(); } void CExtButton::OnLButtonUp(UINT nFlags, CPoint point) { nFlags; point; if( m_bKeyTracking ) return; INT nTrackingHT = _HtMouseOnButton(); BOOL bWasPushed = m_bPushed && m_bPushTracking && (nTrackingHT == m_nTrackingHT); m_bMouseOver = m_bPushed = m_bPushTracking = FALSE; m_nTrackingHT = 0; if( CExtMouseCaptureSink::GetCapture() == GetSafeHwnd() ) CExtMouseCaptureSink::ReleaseCapture(); Invalidate(); UpdateWindow(); if( !bWasPushed ) return; //CButton::OnLButtonDown(nFlags, point); if( IsWindowEnabled() && IsWindowVisible() ) _OnClick( false, (m_bSeparatedDropDown && nTrackingHT == 2) ? true : false ); } void CExtButton::_OnClick( bool bSelectAny, bool bSeparatedDropDownClicked ) { if( (!m_bSeparatedDropDown) || bSeparatedDropDownClicked ) { if( _OnTrackPopup( bSelectAny ) ) return; } CWnd * pWnd = GetParent(); ASSERT( pWnd != NULL ); ASSERT_VALID( pWnd ); if( m_menu.GetSafeHmenu() == NULL || (m_bSeparatedDropDown && (!bSeparatedDropDownClicked)) ) { HWND hWndThis = GetSafeHwnd(); int nDlgCtrlID = GetDlgCtrlID(); pWnd->SendMessage( WM_COMMAND, MAKEWPARAM(nDlgCtrlID,BN_CLICKED), (LPARAM)m_hWnd ); if( ::IsWindow(hWndThis) ) { Invalidate(); UpdateWindow(); } return; } } bool CExtButton::_IsMenuAvail() { if( m_menu.GetSafeHmenu() == NULL ) return false; return true; } bool CExtButton::_OnTrackPopup( bool bSelectAny ) { if( m_menu.GetSafeHmenu() == NULL ) return false; ASSERT( ::IsMenu(m_menu.GetSafeHmenu()) ); VERIFY( g_CmdManager->UpdateFromMenu( g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() ), m_menu.GetSafeHmenu() ) ); CExtPopupMenuWnd * pPopup = new CExtPopupMenuWnd; pPopup->SetLeftAreaWidth( m_nMenuLeftAreaWidth ); CWnd * pWnd = GetParent(); ASSERT_VALID( pWnd ); DWORD dwAlignOpt = 0; DWORD dwMenuOpt = m_dwMenuOpt; while( pWnd->IsKindOf(RUNTIME_CLASS(CControlBar)) ) { if( dwAlignOpt == 0 && ((CControlBar *)pWnd)->m_pDockBar != NULL ) { ASSERT_VALID( ((CControlBar *)pWnd)->m_pDockBar ); dwMenuOpt &= ~TPMX_ALIGN_MASK; UINT nDockBarID = ((CControlBar *)pWnd)->m_pDockBar->GetDlgCtrlID(); switch( nDockBarID ) { case AFX_IDW_DOCKBAR_TOP: dwAlignOpt = TPMX_TOPALIGN; break; case AFX_IDW_DOCKBAR_BOTTOM: dwAlignOpt = TPMX_BOTTOMALIGN; break; case AFX_IDW_DOCKBAR_LEFT: dwAlignOpt = TPMX_LEFTALIGN; break; case AFX_IDW_DOCKBAR_RIGHT: dwAlignOpt = TPMX_RIGHTALIGN; break; case AFX_IDW_DOCKBAR_FLOAT: dwAlignOpt = TPMX_TOPALIGN; break; #ifdef _DEBUG default: ASSERT( FALSE ); break; #endif // _DEBUG } // switch( nDockBarID ) } // if( dwAlignOpt == 0 && ((CControlBar *)pWnd)->m_pDockBar != NULL ) pWnd = pWnd->GetParent(); if( pWnd->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) ) { pWnd = pWnd->GetParentFrame(); ASSERT_VALID( pWnd ); break; } } ASSERT( pWnd != NULL ); ASSERT_VALID( pWnd ); VERIFY( pPopup->UpdateFromMenu( pWnd->GetSafeHwnd(), &m_menu ) ); CRect wr; GetWindowRect( &wr ); CPoint pt = wr.CenterPoint(); SetFocus(); if( m_bAutoChangeID ) { UINT nResultCmdID = 0; if( !pPopup->TrackPopupMenu( dwMenuOpt | dwAlignOpt | ( (bSelectAny) ? TPMX_SELECT_ANY : 0 ) | TPMX_DO_MESSAGE_LOOP | TPMX_NO_WM_COMMAND | TPMX_COMBINE_DEFAULT, pt.x, pt.y, &wr, this, _CbPaintCombinedContent, & nResultCmdID, true ) ) { delete pPopup; ASSERT( FALSE ); } else { if( nResultCmdID != 0 ) { SetDlgCtrlID( nResultCmdID ); if( m_bAutoChangeCmdIcon ) { __EXT_MFC_SAFE_LPCTSTR sProfileName = g_CmdManager->ProfileNameFromWnd(m_hWnd); if( sProfileName != NULL ) { CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( sProfileName, nResultCmdID ); if( pCmdItem != NULL ) { CExtSafeString sText = pCmdItem->m_sToolbarText.IsEmpty() ? pCmdItem->m_sMenuText : pCmdItem->m_sToolbarText ; SetWindowText( sText ); HICON hIcon = g_CmdManager->CmdGetHICON( sProfileName, nResultCmdID ); if( hIcon == NULL ) SetIcon( NULL ); { CExtCmdIcon _icon( hIcon, true ); SetIcon( _icon.DetachAsHICON() ); } } } } CWnd * pWnd = GetParent(); ASSERT( pWnd != NULL ); ASSERT_VALID( pWnd ); HWND hWndThis = GetSafeHwnd(); pWnd->SendMessage( WM_COMMAND, MAKEWPARAM(nResultCmdID,BN_CLICKED), (LPARAM)m_hWnd ); if( ::IsWindow(hWndThis) ) { Invalidate(); UpdateWindow(); } } } } // if( m_bAutoChangeID ) else { if( !pPopup->TrackPopupMenu( dwMenuOpt | dwAlignOpt | ( (bSelectAny) ? TPMX_SELECT_ANY : 0 ) //| TPMX_DO_MESSAGE_LOOP | TPMX_COMBINE_DEFAULT, pt.x, pt.y, &wr, this, _CbPaintCombinedContent, NULL, true ) ) { delete pPopup; ASSERT( FALSE ); } } // else from if( m_bAutoChangeID ) return true; } void CExtButton::_CbPaintCombinedContent( LPVOID pCookie, CDC & dc, const CWnd & refWndMenu, const CRect & rcExcludeArea, // in screen coords int eCombineAlign // CExtPopupMenuWnd::e_combine_align_t values ) { pCookie; dc; refWndMenu; rcExcludeArea; eCombineAlign; ASSERT( dc.GetSafeHdc() != NULL ); ASSERT( refWndMenu.GetSafeHwnd() != NULL ); CExtButton * pBtn = (CExtButton *)pCookie; ASSERT( pBtn != NULL ); ASSERT_VALID( pBtn ); ASSERT( pBtn->IsKindOf(RUNTIME_CLASS(CExtButton)) ); ASSERT( eCombineAlign != CExtPopupMenuWnd::__CMBA_NONE ); if( rcExcludeArea.IsRectEmpty() ) return; CRect rcClientBar,rcClientExcludeArea; pBtn->GetClientRect( &rcClientBar ); pBtn->ClientToScreen( &rcClientBar ); refWndMenu.GetClientRect( &rcClientExcludeArea ); refWndMenu.ClientToScreen( &rcClientExcludeArea ); CPoint ptOffset = rcClientBar.TopLeft() - rcClientExcludeArea.TopLeft() ; CPoint ptViewportOrg = dc.GetViewportOrg(); dc.SetViewportOrg( ptOffset ); pBtn->_RenderImpl(dc,true); dc.SetViewportOrg( ptViewportOrg ); } void CExtButton::_RenderImpl( CDC & dc, bool bTransparent // = false ) { ASSERT_VALID( this ); CRect rectClient; GetClientRect( &rectClient ); CString sWindowText( _T("") ); GetWindowText( sWindowText ); bool bDrawFocusRect = (GetFocus() == this) ? true : false; bool bDefault = GetDefault() ? true : false; bool bPushed = (m_bPushed || GetCheck()) ? true : false; bool bEnabled = IsWindowEnabled() ? true : false; bool bFlat = GetFlat() ? true : false; bool bHover = ( m_bMouseOver && !CExtPopupMenuWnd::IsMenuTracking() ) ? true : false; HICON hIcon = (bHover) ? m_hIconIn : m_hIconOut; if( GetParent()->IsKindOf(RUNTIME_CLASS(CControlBar)) ) { bDrawFocusRect = false; bFlat = true; } if( (! bTransparent ) && (! (bHover || bPushed) ) && g_PaintManager->GetCb2DbTransparentMode(this) ) { CExtPaintManager::stat_ExcludeChildAreas( dc, GetSafeHwnd(), CExtPaintManager::stat_DefExcludeChildAreaCallback ); g_PaintManager->PaintDockerBkgnd( dc, this ); bTransparent = true; } CExtCmdIcon icon( hIcon, false ); CExtPaintManager::PAINTPUSHBUTTONDATA _ppbd( this, true, rectClient, (LPCTSTR)sWindowText, &icon, bFlat, bHover, bPushed, false, bEnabled, m_bDrawBorder ? true : false, bDrawFocusRect, bDefault, m_nAlign, NULL, _IsMenuAvail(), 0, bTransparent ); _ppbd.m_bSeparatedDropDown = m_bSeparatedDropDown ? true : false; if( _ppbd.m_bSeparatedDropDown && m_nTrackingHT == 2 && _ppbd.m_bPushed ) { _ppbd.m_bPushed = false; _ppbd.m_bPushedDropDown = true; // _ppbd.m_bHover = false; } g_PaintManager->PaintPushButton( dc, _ppbd ); icon.DetachAsHICON(); } void CExtButton::_DrawImpl( CDC & dc, bool bTransparent // = false ) { CRect rectClient; GetClientRect( &rectClient ); CExtMemoryDC dcmm( &dc, &rectClient ); _RenderImpl(dcmm,bTransparent); } void CExtButton::OnPaint() { CPaintDC dcPaint( this ); _DrawImpl( dcPaint ); } BOOL CExtButton::OnEraseBkgnd(CDC* pDC) { pDC; // _DrawImpl( *pDC ); return FALSE; } void CExtButton::OnEnable(BOOL bEnable) { CButton::OnEnable(bEnable); CClientDC dc(this); _DrawImpl( dc ); } CExtColorButton::CExtColorButton() { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) m_bUseStdColorDlg = false; #else m_bUseStdColorDlg = true; #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) m_bEnableBtnColorDefault = true; m_bEnableBtnColorCustom = true; m_clrDefault = (COLORREF)(-1); // unexisting m_clrSelected = RGB(0,0,0); m_lParamCookie = 0; m_sBtnTextColorDefault = _T(""); m_sBtnTextColorCustom = _T(""); } CExtColorButton::~CExtColorButton() { _FreeWinObjects(); } IMPLEMENT_DYNCREATE(CExtColorButton, CExtButton); BEGIN_MESSAGE_MAP(CExtColorButton, CExtButton) //{{AFX_MSG_MAP(CExtColorButton) //}}AFX_MSG_MAP ON_REGISTERED_MESSAGE( CExtPopupColorMenuWnd::g_nMsgNotifyColorChanged, OnColorChanged ) ON_REGISTERED_MESSAGE( CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally, OnColorChangedFinally ) ON_REGISTERED_MESSAGE( CExtPopupColorMenuWnd::g_nMsgNotifyCustColor, OnColorSelectCustom ) END_MESSAGE_MAP() bool CExtColorButton::_IsMenuAvail() { return true; } bool CExtColorButton::_OnTrackPopup( bool bSelectAny ) { bool bInBar = false; CWnd * pWnd = GetParent(); ASSERT_VALID( pWnd ); DWORD dwAlignOpt = 0; DWORD dwMenuOpt = m_dwMenuOpt; while( pWnd->IsKindOf(RUNTIME_CLASS(CControlBar)) ) { bInBar = true; if( dwAlignOpt == 0 && ((CControlBar *)pWnd)->m_pDockBar != NULL ) { ASSERT_VALID( ((CControlBar *)pWnd)->m_pDockBar ); dwMenuOpt &= ~TPMX_ALIGN_MASK; UINT nDockBarID = ((CControlBar *)pWnd)->m_pDockBar->GetDlgCtrlID(); switch( nDockBarID ) { case AFX_IDW_DOCKBAR_TOP: dwAlignOpt = TPMX_TOPALIGN; break; case AFX_IDW_DOCKBAR_BOTTOM: dwAlignOpt = TPMX_BOTTOMALIGN; break; case AFX_IDW_DOCKBAR_LEFT: dwAlignOpt = TPMX_LEFTALIGN; break; case AFX_IDW_DOCKBAR_RIGHT: dwAlignOpt = TPMX_RIGHTALIGN; break; case AFX_IDW_DOCKBAR_FLOAT: dwAlignOpt = TPMX_TOPALIGN; break; #ifdef _DEBUG default: ASSERT( FALSE ); break; #endif // _DEBUG } // switch( nDockBarID ) } // if( dwAlignOpt == 0 && ((CControlBar *)pWnd)->m_pDockBar != NULL ) pWnd = pWnd->GetParent(); if( pWnd->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) ) { pWnd = pWnd->GetParentFrame(); ASSERT_VALID( pWnd ); break; } } // if( ! ( CExtPopupMenuSite ::g_DefPopupMenuSite.IsEmpty() // || CExtPopupMenuSite ::g_DefPopupMenuSite.IsShutdownMode() // ) // ) // { // CExtPopupMenuWnd * pPopupCurr = // CExtPopupMenuSite ::g_DefPopupMenuSite.GetInstance(); // ASSERT_VALID( pPopupCurr ); // if( pPopupCurr->GetSafeHwnd() != NULL // && ( ::IsWindow(pPopupCurr->GetSafeHwnd()) ) // && pPopupCurr->GetParent()->GetSafeHwnd() == // ( bInBar ? pWnd->GetSafeHwnd() : GetSafeHwnd() ) // ) // return true; // } CExtPopupColorMenuWnd * pPopup = new CExtPopupColorMenuWnd; pPopup->SetLeftAreaWidth( m_nMenuLeftAreaWidth ); pPopup->m_lParamCookie = m_lParamCookie; VERIFY( pPopup->CreatePopupMenu( bInBar ? pWnd->GetSafeHwnd() : GetSafeHwnd() ) ); pPopup->m_bEnableBtnColorDefault = m_bEnableBtnColorDefault; pPopup->m_bEnableBtnColorCustom = m_bEnableBtnColorCustom; pPopup->m_clrDefault = m_clrDefault; pPopup->m_clrInitial = m_clrSelected; if( !m_sBtnTextColorDefault.IsEmpty() ) pPopup->m_sBtnTextColorDefault = m_sBtnTextColorDefault; if( !m_sBtnTextColorCustom.IsEmpty() ) pPopup->m_sBtnTextColorCustom = m_sBtnTextColorCustom; CRect wr; GetWindowRect( &wr ); CPoint pt = wr.CenterPoint(); if( bInBar) pWnd->SetFocus(); else SetFocus(); bool bToolMenuTracking = false; if( bInBar ) { CExtToolControlBar::_CloseTrackingMenus(); bToolMenuTracking = true; } if( !pPopup->TrackPopupMenu( dwMenuOpt | dwAlignOpt | ( (bSelectAny) ? TPMX_SELECT_ANY : 0 ) //| TPMX_DO_MESSAGE_LOOP | TPMX_COMBINE_DEFAULT , pt.x, pt.y, &wr, this, _CbPaintCombinedContent, NULL, true ) ) { delete pPopup; ASSERT( FALSE ); } else { if( bToolMenuTracking ) CExtToolControlBar::g_bMenuTracking = true; } return true; } void CExtColorButton::OnGenerateColorBtnIcon( HICON * p_hIcon, bool * p_bDestroyIcon ) { ASSERT( p_hIcon != NULL ); ASSERT( p_bDestroyIcon != NULL ); *p_bDestroyIcon = false; *p_hIcon = CExtPaintManager::stat_GenerateColorIconBox( m_clrSelected ); ASSERT( *p_hIcon != NULL ); if( *p_hIcon != NULL ) *p_bDestroyIcon = true; } void CExtColorButton::_RenderImpl( // non-buffered paint CDC & dc, bool bTransparent // = false ) { HICON hIcon = NULL; bool bDestroyIcon = false; OnGenerateColorBtnIcon( &hIcon, &bDestroyIcon ); CRect rectClient; GetClientRect( &rectClient ); CString sWindowText( _T("") ); GetWindowText( sWindowText ); bool bDrawFocusRect = (GetFocus() == this) ? true : false; bool bDefault = GetDefault() ? true : false; bool bPushed = (m_bPushed || GetCheck()) ? true : false; bool bEnabled = IsWindowEnabled() ? true : false; bool bFlat = GetFlat() ? true : false; bool bHover = ( m_bMouseOver && !CExtPopupMenuWnd::IsMenuTracking() ) ? true : false; if( GetParent()->IsKindOf(RUNTIME_CLASS(CControlBar)) ) { bDrawFocusRect = false; bFlat = true; } if( (! bTransparent ) && (! (bHover || bPushed) ) && g_PaintManager->GetCb2DbTransparentMode(this) ) { CExtPaintManager::stat_ExcludeChildAreas( dc, GetSafeHwnd(), CExtPaintManager::stat_DefExcludeChildAreaCallback ); g_PaintManager->PaintDockerBkgnd( dc, this ); bTransparent = true; } CExtCmdIcon icon( hIcon, false ); CExtPaintManager::PAINTPUSHBUTTONDATA _ppbd( this, true, rectClient, (LPCTSTR)sWindowText, &icon, bFlat, bHover, bPushed, false, bEnabled, (m_bDrawBorder && (!CExtPopupMenuWnd::IsMenuTracking())) ? true : false, (bDrawFocusRect && (!CExtPopupMenuWnd::IsMenuTracking()) && (!sWindowText.IsEmpty()) ) ? true : false, bDefault, m_nAlign, NULL, _IsMenuAvail(), 0, bTransparent ); _ppbd.m_bSeparatedDropDown = m_bSeparatedDropDown ? true : false; if( _ppbd.m_bSeparatedDropDown && m_nTrackingHT == 2 && _ppbd.m_bPushed ) { _ppbd.m_bPushed = false; _ppbd.m_bPushedDropDown = true; // _ppbd.m_bHover = false; } g_PaintManager->PaintPushButton( dc, _ppbd ); icon.DetachAsHICON(); if( hIcon != NULL && bDestroyIcon ) { ::DestroyIcon( hIcon ); } } LRESULT CExtColorButton::OnColorChanged(WPARAM wParam, LPARAM lParam) { wParam; lParam; // m_clrSelected = (COLORREF)wParam; // Invalidate(); // UpdateWindow(); //CExtPopupMenuWnd * pPopup = // CExtPopupMenuWnd::GetTrackingMenu(); // if( pPopup != NULL // && pPopup->GetSafeHwnd() != NULL // ) // pPopup->Invalidate(); return GetParent()->SendMessage( CExtPopupColorMenuWnd::g_nMsgNotifyColorChanged, wParam, lParam ); } LRESULT CExtColorButton::OnColorChangedFinally(WPARAM wParam, LPARAM lParam) { lParam; COLORREF clr = (COLORREF)wParam; m_clrSelected = (clr == ((COLORREF)(-1))) ? RGB(0,0,0) : clr; Invalidate(); UpdateWindow(); return GetParent()->SendMessage( CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally, wParam, lParam ); } LRESULT CExtColorButton::OnColorSelectCustom(WPARAM wParam, LPARAM lParam) { wParam; lParam; if( m_bUseStdColorDlg ) { CColorDialog dlg(m_clrSelected,CC_FULLOPEN,this); if( dlg.DoModal() != IDOK ) return 0; m_clrSelected = dlg.m_cc.rgbResult; } // if( m_bUseStdColorDlg ) else { CExtColorDlg dlg( m_clrSelected,m_clrSelected,this ); if( dlg.DoModal() != IDOK ) return 0; m_clrSelected = dlg.m_clrNew; } // else from if( m_bUseStdColorDlg ) GetParent()->SendMessage( CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally, WPARAM( m_clrSelected ), lParam ); Invalidate(); UpdateWindow(); return 0; } LRESULT CExtButton::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if( message == CExtToolControlBar::g_nMsgContinueTrackMenu ) { _OnTrackPopup( lParam ? true : false ); return (!0); } if( message == WM_NOTIFY && m_wndToolTip.GetSafeHwnd() != NULL && IsWindow( m_wndToolTip.GetSafeHwnd() ) && ((LPNMHDR)lParam) != NULL && ((LPNMHDR)lParam)->hwndFrom == m_wndToolTip.GetSafeHwnd() && ((LPNMHDR)lParam)->code == TTN_SHOW ) ::SetWindowPos( m_wndToolTip.GetSafeHwnd(), HWND_TOP, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE ); if( message == CExtPopupMenuWnd::g_nMsgPrepareMenu || message == CExtPopupMenuWnd::g_nMsgPopupNext || message == CExtPopupMenuWnd::g_nMsgPopupPrev || message == CExtPopupMenuWnd::g_nMsgNotifyMenuExpanded || message == CExtPopupMenuWnd::g_nMsgNotifyMenuClosed || message == CExtPopupMenuWnd::g_nMsgPopupDrawItem || message == CExtPopupMenuWnd::g_nMsgPopupDrawLeftArea ) { CWnd * pParent = GetParent(); if( pParent ) return pParent->SendMessage( message, wParam, lParam ); else return 0; } bool bInvalidate = false; switch( message ) { case WM_MOUSEMOVE: if( CExtToolControlBar::g_bMenuTracking ) { CWnd * pWndParent = GetParent(); if( pWndParent != NULL && pWndParent->IsKindOf(RUNTIME_CLASS(CExtToolControlBar)) ) { _OnTrackPopup( false ); return 0; } } break; case WM_LBUTTONDBLCLK: return 0; //message = WM_LBUTTONDOWN; //break; case BM_SETCHECK: case BM_SETSTATE: case BM_SETSTYLE: #if (WINVER >= 0x0400) case BM_CLICK: case BM_SETIMAGE: #endif case WM_SETTEXT: case WM_SIZE: case WM_WINDOWPOSCHANGED: bInvalidate = true; break; } // switch( message ) LRESULT lResult = CButton::WindowProc( message, wParam, lParam ); // if( // CExtPopupColorMenuWnd::g_nMsgNotifyColorChanged // || CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally // || CExtPopupColorMenuWnd::g_nMsgNotifyCustColor // ) // { // CWnd * pParent = GetParent(); // if( pParent ) // pParent->SendMessage( message, wParam, lParam ); // } if( bInvalidate ) { Invalidate(); UpdateWindow(); } return lResult; } void CExtColorButton::_OnClick( bool bSelectAny, bool bSeparatedDropDownClicked ) { if( (!m_bSeparatedDropDown) || bSeparatedDropDownClicked ) { if( _OnTrackPopup( bSelectAny ) ) return; } CWnd * pWnd = GetParent(); ASSERT( pWnd != NULL ); ASSERT_VALID( pWnd ); pWnd->SendMessage( CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally, (WPARAM)m_clrSelected, m_lParamCookie ); }